home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / djgpp / src / gdb-4.12 / gdb / lynx-nat.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-03  |  7.4 KB  |  316 lines

  1. /* Native-dependent code for LynxOS.
  2.    Copyright 1993 Free Software Foundation, Inc.
  3.  
  4. This file is part of GDB.
  5.  
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include "defs.h"
  21. #include "frame.h"
  22. #include "inferior.h"
  23. #include "target.h"
  24.  
  25. #include <sys/ptrace.h>
  26. #include "/usr/include/sys/wait.h"
  27.  
  28. static unsigned long registers_addr PARAMS ((int pid));
  29.  
  30. #define X(ENTRY)(offsetof(struct econtext, ENTRY))
  31.  
  32. #ifdef I386
  33. /* Mappings from tm-i386v.h */
  34.  
  35. static int regmap[] =
  36. {
  37.   X(eax),
  38.   X(ecx),
  39.   X(edx),
  40.   X(ebx),
  41.   X(esp),            /* sp */
  42.   X(ebp),            /* fp */
  43.   X(esi),
  44.   X(edi),
  45.   X(eip),            /* pc */
  46.   X(flags),            /* ps */
  47.   X(cs),
  48.   X(ss),
  49.   X(ds),
  50.   X(es),
  51.   X(ecode),            /* Lynx doesn't give us either fs or gs, so */
  52.   X(fault),            /* we just substitute these two in the hopes
  53.                    that they are useful. */
  54. };
  55. #endif
  56.  
  57. #ifdef M68K
  58. /* Mappings from tm-m68k.h */
  59.  
  60. static int regmap[] =
  61. {
  62.   X(regs[0]),            /* d0 */
  63.   X(regs[1]),            /* d1 */
  64.   X(regs[2]),            /* d2 */
  65.   X(regs[3]),            /* d3 */
  66.   X(regs[4]),            /* d4 */
  67.   X(regs[5]),            /* d5 */
  68.   X(regs[6]),            /* d6 */
  69.   X(regs[7]),            /* d7 */
  70.   X(regs[8]),            /* a0 */
  71.   X(regs[9]),            /* a1 */
  72.   X(regs[10]),            /* a2 */
  73.   X(regs[11]),            /* a3 */
  74.   X(regs[12]),            /* a4 */
  75.   X(regs[13]),            /* a5 */
  76.   X(regs[14]),            /* fp */
  77.   offsetof (st_t, usp) - offsetof (st_t, ec), /* sp */
  78.   X(status),            /* ps */
  79.   X(pc),
  80.  
  81.   X(fregs[0*3]),        /* fp0 */
  82.   X(fregs[1*3]),        /* fp1 */
  83.   X(fregs[2*3]),        /* fp2 */
  84.   X(fregs[3*3]),        /* fp3 */
  85.   X(fregs[4*3]),        /* fp4 */
  86.   X(fregs[5*3]),        /* fp5 */
  87.   X(fregs[6*3]),        /* fp6 */
  88.   X(fregs[7*3]),        /* fp7 */
  89.  
  90.   X(fcregs[0]),            /* fpcontrol */
  91.   X(fcregs[1]),            /* fpstatus */
  92.   X(fcregs[2]),            /* fpiaddr */
  93.   X(ssw),            /* fpcode */
  94.   X(fault),            /* fpflags */
  95. };
  96. #endif
  97.  
  98. /* Return the offset relative to the start of the per-thread data to the
  99.    saved context block.  */
  100.  
  101. static unsigned long
  102. registers_addr(pid)
  103.      int pid;
  104. {
  105.   CORE_ADDR stblock;
  106.   int ecpoff = offsetof(st_t, ecp);
  107.   CORE_ADDR ecp;
  108.  
  109.   errno = 0;
  110.   stblock = (CORE_ADDR) ptrace (PTRACE_THREADUSER, pid, (PTRACE_ARG3_TYPE)0,
  111.                 0);
  112.   if (errno)
  113.     perror_with_name ("registers_addr(PTRACE_THREADUSER)");
  114.  
  115.   ecp = (CORE_ADDR) ptrace (PTRACE_PEEKTHREAD, pid, (PTRACE_ARG3_TYPE)ecpoff,
  116.                 0);
  117.   if (errno)
  118.     perror_with_name ("registers_addr(PTRACE_PEEKTHREAD)");
  119.  
  120.   return ecp - stblock;
  121. }
  122.  
  123. /* Fetch one or more registers from the inferior.  REGNO == -1 to get
  124.    them all.  We actually fetch more than requested, when convenient,
  125.    marking them as valid so we won't fetch them again.  */
  126.  
  127. void
  128. fetch_inferior_registers (regno)
  129.      int regno;
  130. {
  131.   int reglo, reghi;
  132.   int i;
  133.   unsigned long ecp;
  134.  
  135.   if (regno == -1)
  136.     {
  137.       reglo = 0;
  138.       reghi = NUM_REGS - 1;
  139.     }
  140.   else
  141.     reglo = reghi = regno;
  142.  
  143.   ecp = registers_addr (inferior_pid);
  144.  
  145.   for (regno = reglo; regno <= reghi; regno++)
  146.     {
  147.       char buf[MAX_REGISTER_RAW_SIZE];
  148.       int ptrace_fun = PTRACE_PEEKTHREAD;
  149.  
  150. #ifdef PTRACE_PEEKUSP
  151.       ptrace_fun = regno == SP_REGNUM ? PTRACE_PEEKUSP : PTRACE_PEEKTHREAD;
  152. #endif
  153.  
  154.       for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
  155.     {
  156.       unsigned int reg;
  157.  
  158.       errno = 0;
  159.       reg = ptrace (ptrace_fun, inferior_pid,
  160.             (PTRACE_ARG3_TYPE) (ecp + regmap[regno] + i), 0);
  161.       if (errno)
  162.         perror_with_name ("fetch_inferior_registers(ptrace)");
  163.   
  164.       *(int *)&buf[i] = reg;
  165.     }
  166.       supply_register (regno, buf);
  167.     }
  168. }
  169.  
  170. /* Store our register values back into the inferior.
  171.    If REGNO is -1, do this for all registers.
  172.    Otherwise, REGNO specifies which register (so we can save time).  */
  173.  
  174. void
  175. store_inferior_registers (regno)
  176.      int regno;
  177. {
  178.   int reglo, reghi;
  179.   int i;
  180.   unsigned long ecp;
  181.  
  182.   if (regno == -1)
  183.     {
  184.       reglo = 0;
  185.       reghi = NUM_REGS - 1;
  186.     }
  187.   else
  188.     reglo = reghi = regno;
  189.  
  190.   ecp = registers_addr (inferior_pid);
  191.  
  192.   for (regno = reglo; regno <= reghi; regno++)
  193.     {
  194.       int ptrace_fun = PTRACE_POKEUSER;
  195.  
  196. #ifdef PTRACE_POKEUSP
  197.       ptrace_fun = regno == SP_REGNUM ? PTRACE_POKEUSP : PTRACE_POKEUSER;
  198. #endif
  199.  
  200.       for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
  201.     {
  202.       unsigned int reg;
  203.  
  204.       reg = *(unsigned int *)®isters[REGISTER_BYTE (regno) + i];
  205.  
  206.       errno = 0;
  207.       ptrace (ptrace_fun, inferior_pid,
  208.           (PTRACE_ARG3_TYPE) (ecp + regmap[regno] + i), reg);
  209.       if (errno)
  210.         perror_with_name ("PTRACE_POKEUSER");
  211.     }
  212.     }
  213. }
  214.  
  215. /* Wait for child to do something.  Return pid of child, or -1 in case
  216.    of error; store status through argument pointer OURSTATUS.  */
  217.  
  218. int
  219. child_wait (pid, ourstatus)
  220.      int pid;
  221.      struct target_waitstatus *ourstatus;
  222. {
  223.   int save_errno;
  224.   int thread;
  225.   int status;
  226.  
  227.   while (1)
  228.     {
  229.       int sig;
  230.  
  231.       if (attach_flag)
  232.     set_sigint_trap();    /* Causes SIGINT to be passed on to the
  233.                    attached process. */
  234.       pid = wait (status);
  235.       save_errno = errno;
  236.  
  237.       if (attach_flag)
  238.     clear_sigint_trap();
  239.  
  240.       if (pid == -1)
  241.     {
  242.       if (save_errno == EINTR)
  243.         continue;
  244.       fprintf_unfiltered (gdb_stderr, "Child process unexpectedly missing: %s.\n",
  245.            safe_strerror (save_errno));
  246.       /* Claim it exited with unknown signal.  */
  247.       ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
  248.       ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
  249.       return -1;
  250.     }
  251.  
  252.       if (pid != PIDGET (inferior_pid))    /* Some other process?!? */
  253.     continue;
  254.  
  255. /*      thread = WIFTID (status);*/
  256.       thread = status >> 16;
  257.  
  258.       /* Initial thread value can only be acquired via wait, so we have to
  259.      resort to this hack.  */
  260.  
  261.       if (TIDGET (inferior_pid) == 0)
  262.     {
  263.       inferior_pid = BUILDPID (inferior_pid, thread);
  264.       add_thread (inferior_pid);
  265.     }
  266.  
  267.       pid = BUILDPID (pid, thread);
  268.  
  269.       store_waitstatus (ourstatus, status);
  270.  
  271.       return pid;
  272.     }
  273. }
  274.  
  275. /* Convert a Lynx process ID to a string.  Returns the string in a static
  276.    buffer.  */
  277.  
  278. char *
  279. lynx_pid_to_str (pid)
  280.      int pid;
  281. {
  282.   static char buf[40];
  283.  
  284.   sprintf (buf, "process %d thread %d", PIDGET (pid), TIDGET (pid));
  285.  
  286.   return buf;
  287. }
  288.  
  289. /* Extract the register values out of the core file and store
  290.    them where `read_register' will find them.
  291.  
  292.    CORE_REG_SECT points to the register values themselves, read into memory.
  293.    CORE_REG_SIZE is the size of that area.
  294.    WHICH says which set of registers we are handling (0 = int, 2 = float
  295.          on machines where they are discontiguous).
  296.    REG_ADDR is the offset from u.u_ar0 to the register values relative to
  297.             core_reg_sect.  This is used with old-fashioned core files to
  298.         locate the registers in a large upage-plus-stack ".reg" section.
  299.         Original upage address X is at location core_reg_sect+x+reg_addr.
  300.  */
  301.  
  302. void
  303. fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
  304.      char *core_reg_sect;
  305.      unsigned core_reg_size;
  306.      int which;
  307.      unsigned reg_addr;
  308. {
  309.   struct st_entry s;
  310.   unsigned int regno;
  311.  
  312.   for (regno = 0; regno < NUM_REGS; regno++)
  313.     supply_register (regno, core_reg_sect + offsetof (st_t, ec)
  314.              + regmap[regno]);
  315. }
  316.